package jp.ac.u_tokyo.dch.interceptor;

import java.lang.reflect.Method;
import java.util.List;

import jp.ac.u_tokyo.dch.core.db.DBConnection;
import jp.ac.u_tokyo.dch.service.DaoServiceAware;
import jp.ac.u_tokyo.dch.service.Transaction;
import jp.ac.u_tokyo.dch.util.common.CommonDBConnection;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;
import com.opensymphony.xwork2.interceptor.ExceptionHolder;
import com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor;
/**
 * @version 1.1
 */
public class DbConnectionAwareInterceptor extends ExceptionMappingInterceptor {

	private static final long serialVersionUID = 1L;

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
        String result;
        DBConnection dbConnection = null;
        boolean transaction = false;
        try {

        	final Object action = invocation.getAction();

        	if (action instanceof DaoServiceAware) {

        		dbConnection = CommonDBConnection.getDbconnection();

        		String methodName = invocation.getProxy().getMethod();

        		Class<?> cls = action.getClass();

        		Method method = cls.getMethod(methodName);

        		// メソッドにアノテーションがあるかチェック
        		if( method.isAnnotationPresent(Transaction.class)) {
        			dbConnection.setAutoCommit(false);
        			transaction = true;
        		}

                ((DaoServiceAware) action).setDBConnection(dbConnection);
        	}

            result = invocation.invoke();

            if (transaction) {
            	dbConnection.commit();
            }

            CommonDBConnection.closeConnection(dbConnection);
        } catch (Exception e) {
        	if (isLogEnabled()) {
                handleLogging(e);
            }
        	if (transaction) {
        		dbConnection.rollback();
        	}

        	CommonDBConnection.closeConnection(dbConnection);
            List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
            String mappedResult = this.findResultFromExceptions(exceptionMappings, e);
            if (mappedResult != null) {
                result = mappedResult;
                publishException(invocation, new ExceptionHolder(e));
            } else {
                throw e;
            }
        }

		return result;
	}


}